import logging
import sys
import time
import unittest

from base_test_class import BaseTestCase
from product_test import ProductTest
from selenium.webdriver.common.by import By

logger = logging.getLogger(__name__)

"""
Tests Notes functionality on all levels (Engagement, Test, and Finding)
Private and public notes are tested
"""


class NoteTest(BaseTestCase):

    def uncollapse_all(self, driver):
        elems = driver.find_elements(By.NAME, "collapsible")
        for elem in elems:
            elem.click()
            time.sleep(0.5)
        return driver

    def create_public_note(self, driver, level):
        time.sleep(1)
        if not driver.find_element(By.ID, "add_note").is_displayed():
            self.uncollapse_all(driver)
        driver.find_element(By.ID, "id_entry").send_keys("Test public note")
        driver.find_element(By.ID, "add_note").click()
        time.sleep(1)
        if not driver.find_element(By.ID, "add_note").is_displayed():
            self.uncollapse_all(driver)
        text = driver.find_element(By.TAG_NAME, "body").text
        self.assertIn("Test public note", text, f"Public note created at the {level} level")

    def create_private_note(self, driver, level):
        time.sleep(1)
        if not driver.find_element(By.ID, "add_note").is_displayed():
            self.uncollapse_all(driver)
        driver.find_element(By.ID, "id_entry").send_keys("Test private note")
        driver.find_element(By.ID, "id_private").click()
        driver.find_element(By.ID, "add_note").click()
        time.sleep(1)
        if not driver.find_element(By.ID, "add_note").is_displayed():
            self.uncollapse_all(driver)
        text = driver.find_element(By.TAG_NAME, "body").text
        note_present = "Test public note" in text
        private_status = "(will not appear in report)" in text
        pass_test = note_present and private_status
        if not pass_test:
            logger.info("Private note note created at the %s level", level)
        self.assertTrue(pass_test)

    def test_finding_note(self):
        driver = self.driver
        self.goto_all_findings_list(driver)
        driver.find_element(By.LINK_TEXT, "App Vulnerable to XSS").click()
        self.create_public_note(driver, "Finding")
        self.create_private_note(driver, "Finding")

    def test_test_note(self):
        driver = self.driver
        self.goto_all_engagements_overview(driver)
        driver.find_element(By.PARTIAL_LINK_TEXT, "Ad Hoc Engagement").click()
        driver.find_element(By.PARTIAL_LINK_TEXT, "Pen Test").click()
        self.create_public_note(driver, "Test")
        self.create_private_note(driver, "Test")

    def test_engagement_note(self):
        driver = self.driver
        self.goto_all_engagements_overview(driver)
        driver.find_element(By.PARTIAL_LINK_TEXT, "Ad Hoc Engagement").click()
        self.create_public_note(driver, "Engagement")
        self.create_private_note(driver, "Engagement")


def suite():
    suite = unittest.TestSuite()
    suite.addTest(BaseTestCase("test_login"))
    suite.addTest(BaseTestCase("disable_block_execution"))
    suite.addTest(ProductTest("test_create_product"))
    suite.addTest(ProductTest("test_add_product_finding"))
    suite.addTest(NoteTest("test_finding_note"))
    suite.addTest(NoteTest("test_test_note"))
    suite.addTest(NoteTest("test_engagement_note"))
    suite.addTest(ProductTest("test_delete_product"))
    return suite


if __name__ == "__main__":
    runner = unittest.TextTestRunner(descriptions=True, failfast=True, verbosity=2)
    ret = not runner.run(suite()).wasSuccessful()
    BaseTestCase.tearDownDriver()
    sys.exit(ret)
